package com.seeyon.ctp.rest.resources;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.lzmzj.kit.FormCap4Kit;
import com.seeyon.apps.lzmzj.kit.HttpKit;
import com.seeyon.apps.lzmzj.kit.StrKit;
import com.seeyon.apps.lzmzj.manager.TemporaryDataManager;
import com.seeyon.apps.lzmzj.po.TemporaryDataPO;
import com.seeyon.apps.lzmzj.util.QRCodeUtil;
import com.seeyon.cap4.form.bean.*;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager;
import com.seeyon.ctp.common.log.CtpLogFactory;
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.util.UUIDLong;
import org.apache.commons.logging.Log;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Path("jssdk")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON})
public class CreateQRCodeResources extends BaseResource {

    private static final Log log = CtpLogFactory.getLog(CreateQRCodeResources.class);

    private String zcly_lowformCode = AppContext.getSystemProperty("oaFormCode.zcly_lowformCode");
    private String localAddr = AppContext.getRawRequest().getLocalAddr();
    private String port = String.valueOf(AppContext.getRawRequest().getLocalPort());
    private String tokenUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/token";
    private String file_url = "http://" + localAddr + ":" + port + "/seeyon/rest/attachment?token=";
    private String bpmUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/bpm/process/start";

    private SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);


    /*资产档案模版编码*/
    private static final String zcda_unFlowformCode = AppContext.getSystemProperty("oaFormCode.zcda_unFlowformCode");

    private OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
    private EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");
    private CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");
    private TemporaryDataManager temporaryDataManager = (TemporaryDataManager) AppContext.getBean("temporaryDataManager");


    /**
     * 添加数据ID集合
     * <p>
     * 该方法用于接收一个包含数据ID集合的参数，保存这些数据ID到数据库中，并返回生成的临时数据ID和当前用户ID
     * 主要用于在系统中生成和关联二维码数据ID，以便于后续的二维码生成和管理
     *
     * @param param 包含需要生成二维码的数据ID集合的参数
     * @return 返回一个包含生成的临时数据ID和当前用户ID的Map对象
     */
    @POST
    @Path("dataIds")
    public Response addDataIds(Map<String, Object> param) {
        // 记录接收到的需要生成二维码数据ID集合的参数
        log.info("需要生成二维码数据ID集合：" + JSON.toJSONString(param));

        // 创建一个新的TemporaryDataPO对象，用于存储数据ID集合
        TemporaryDataPO temporaryDataPO = new TemporaryDataPO();
        // 如果是新的对象，则生成一个唯一的ID
        temporaryDataPO.setIdIfNew();
        // 设置创建时间
        temporaryDataPO.setCreateTime(new Date());
        // 设置临时数据ID，这里是将传入的ids参数转换为字符串并去除中括号
        temporaryDataPO.setTemporaryDataId(StrKit.str(param.get("ids")).replace("[", "").replace("]", ""));

        // 保存临时数据到数据库
        temporaryDataManager.save(temporaryDataPO);

        // 创建一个结果Map，用于存储和返回生成的临时数据ID和当前用户ID
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 放入生成的临时数据ID
        resultMap.put("dataId", StrKit.str(temporaryDataPO.getId()));
        // 放入当前用户ID
        resultMap.put("userId", StrKit.str(AppContext.getCurrentUser().getId()));

        // 返回包含结果信息的响应
        return ok(resultMap);
    }


    /**
     * 创建二维码
     * <p>
     * 该方法通过接收一个包含数据ID和用户ID的参数映射，来生成并上传二维码图片作为表单附件
     * 它首先验证参数的正确性，然后根据数据ID获取表单数据，为每个数据生成二维码，并将二维码图片上传到服务器
     * 最后，它将上传的文件URL与表单数据关联，保存到数据库，并返回结果映射
     *
     * @param param 包含"dataId"和"userId"的参数映射，用于生成二维码
     * @return 返回一个包含操作结果代码、消息和数据的Response对象
     * @throws Exception 如果操作失败，抛出异常
     */
    @POST
    @Path("createQRcode")
    public Response createQRcode(Map<String, Object> param) throws Exception {
        // 初始化结果映射和数据列表
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();

        try {
            // 日志记录临时数据ID
            log.info("临时数据ID:" + JSON.toJSONString(param));

            // 获取并验证数据ID
            String dataId = StrKit.str(param.get("dataId"));
            if ("".equals(dataId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "数据ID不能为空值");
                resultMap.put("data", dataList);
                return ok(resultMap);
            }

            // 获取并验证用户ID
            String userId = StrKit.str(param.get("userId"));
            if ("".equals(userId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "人员ID不能为空值");
                resultMap.put("data", dataList);
                return ok(resultMap);
            }

            // 根据用户ID获取用户信息
            V3xOrgMember v3xOrgMember = orgManager.getMemberById(Long.parseLong(userId));

            // 根据表单代码获取表单信息
            FormBean formBean = cap4FormManager.getFormByFormCode(zcda_unFlowformCode);
            List<FormFieldBean> allFieldBeans = formBean.getAllFieldBeans();

            // 生成令牌并构建文件URL
            String tokenId = HttpKit.getToken(v3xOrgMember.getLoginName(), tokenUrl);
            String fileUrl_new = file_url + tokenId;

            // 根据数据ID获取临时数据
            TemporaryDataPO temporaryDataPO = temporaryDataManager.findDataById(Long.parseLong(dataId));
            if (temporaryDataPO == null) {
                resultMap.put("code", 500);
                resultMap.put("message", "dataId[" + dataId + "]有误,未查询到数据!");
                resultMap.put("data", dataList);
                return ok(resultMap);
            }
            String temporaryDataId = StrKit.str(temporaryDataPO.getTemporaryDataId());
            List<String> list = Arrays.asList(temporaryDataId.split(","));

            // 遍历每个表单数据ID，生成并上传二维码
            for (String formDataId : list) {
                Long sub_reference = UUIDLong.longUUID();
                FormDataMasterBean formDataMasterBean = cap4FormManager.getDataMasterBeanById(Long.parseLong(formDataId.trim()), formBean, null);
                if (formDataMasterBean != null) {
                    Map<String, Object> dataMap = new HashMap<String, Object>();
                    for (FormFieldBean formFieldBean : allFieldBeans) {
                        String fieldDesc = StrKit.str(formFieldBean.getDesc());
                        if (!"".equals(fieldDesc) && !fieldDesc.contains("_查询")) {
                            String fieldType = formFieldBean.getInputType();
                            String fieldName = formFieldBean.getName();
                            String fieldValue = StrKit.str(formDataMasterBean.getFieldValue(fieldName));
                            String fieldValue_new = getData(fieldValue, fieldType);
                            dataMap.put(fieldDesc, fieldValue_new);
                        }
                    }

                    // 生成二维码图片并上传
                    String assetsCode = StrKit.str(formDataMasterBean.getFieldValue(formBean.getFieldBeanByDisplay("资产编号").getName()));
                    String systemUrl = SystemEnvironment.getBaseFolder().replaceAll("\\\\", "/");
                    String pathUrl = systemUrl + "/upload/customBarCode/";
                    File filePath = new File(pathUrl);
                    if (!filePath.exists()) {
                        filePath.mkdirs();
                    }
                    QRCodeUtil.createImage(formDataId.trim(), 300, 300, assetsCode, "png", pathUrl);
                    String imageUrl = pathUrl + assetsCode + ".png";
                    File barImageFile = new File(imageUrl);

                    String fileResult = HttpKit.uploadFile(fileUrl_new, barImageFile);
                    barImageFile.delete();
                    String fileUrl = StrKit.getFileUrl(fileResult);

                    // 将上传的文件URL与表单数据关联并保存
                    FormCap4Kit.addAttachment(Long.parseLong(fileUrl), formDataMasterBean.getId(), sub_reference);
                    formDataMasterBean.addFieldValue(formBean.getFieldBeanByDisplay("二维码附件").getName(), sub_reference);
                    cap4FormManager.saveOrUpdateFormData(formDataMasterBean, formBean.getId(), true, null);

                    dataMap.put("imageUrl", formDataId.trim());
                    if (dataMap.containsKey("占进程")) {
                        dataMap.remove("占进程");
                    }
                    dataList.add(dataMap);
                }
            }

            // 返回成功结果
            resultMap.put("code", 200);
            resultMap.put("message", "");
            resultMap.put("data", dataList);
            return ok(resultMap);
        } catch (Exception e) {
            log.error("二维码生成接口异常信息:", e);
            // 返回异常结果
            resultMap.put("code", 500);
            resultMap.put("message", e.getMessage());
            resultMap.put("data", dataList);
            return ok(resultMap);
        }
    }


    /**
     * 根据ID获取数据
     * <p>
     * 该方法通过POST请求接收参数，并根据提供的ID查询数据
     * 主要用于从服务端获取特定的数据信息
     *
     * @param param 包含查询ID的参数映射表
     * @return 返回查询结果的响应对象
     * @throws Exception 如果查询过程中发生错误，则抛出异常
     */
    @POST
    @Path("getDataById")
    public Response getDataById(Map<String, Object> param) throws Exception {
        // 记录查询数据ID的日志
        log.info("需要查询的数据ID：" + JSON.toJSONString(param));

        // 初始化用于存储数据的Map
        Map<String, Object> dataMap = new HashMap<String, Object>();
        // 初始化用于存储结果的Map
        Map<String, Object> resultMap = new HashMap<String, Object>();

        try {
            // 获取并验证数据ID
            String dataId = StrKit.str(param.get("dataId"));
            if ("".equals(dataId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "数据ID不能为空值");
                resultMap.put("data", dataMap);
                return ok(resultMap);
            }

            // 获取并验证用户ID
            String userId = StrKit.str(param.get("userId"));
            if ("".equals(userId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "人员ID不能为空值");
                resultMap.put("data", dataMap);
                return ok(resultMap);
            }

            // 通过表单代码获取表单对象
            FormBean formBean = cap4FormManager.getFormByFormCode(zcda_unFlowformCode);
            // 获取表单中所有的字段对象
            List<FormFieldBean> allFieldBeans = formBean.getAllFieldBeans();

            /* 资产档案表数据对象 */
            // 根据数据ID获取表单主数据对象
            FormDataMasterBean formDataMasterBean = cap4FormManager.getDataMasterBeanById(Long.parseLong(dataId.trim()), formBean, null);
            if (formDataMasterBean != null) {
                // 遍历所有字段对象，填充数据Map
                for (FormFieldBean formFieldBean : allFieldBeans) {
                    String fieldDesc = StrKit.str(formFieldBean.getDesc());
                    if (!"".equals(fieldDesc)) {
                        String fieldType = formFieldBean.getInputType();
                        String fieldName = formFieldBean.getName();
                        String fieldValue = StrKit.str(formDataMasterBean.getFieldValue(fieldName));
                        String fieldValue_new = getData(fieldValue, fieldType);
                        dataMap.put(fieldDesc.replaceAll("_查询", ""), fieldValue_new);
                        dataMap.put("id", StrKit.str(formDataMasterBean.getId()));
                    }
                }
            }

            // 返回成功结果
            resultMap.put("code", 200);
            resultMap.put("message", "");
            if (dataMap.containsKey("占进程")) {
                dataMap.remove("占进程");
            }
            resultMap.put("data", dataMap);
            return ok(resultMap);
        } catch (Exception e) {
            log.error("根据ID获取数据接口异常信息：", e);
            // 返回异常结果
            resultMap.put("code", 500);
            resultMap.put("message", e.getMessage());
            resultMap.put("data", dataMap);
            return ok(resultMap);
        }
    }

    /**
     * 盘点接口，用于记录资产的盘点信息
     *
     * @param param 包含盘点所需数据的参数映射，包括数据ID和用户ID
     * @return 返回一个包含盘点结果的Response对象
     * @throws Exception 如果操作失败，抛出异常
     */
    @POST
    @Path("assets/inventory")
    public Response assetsInventory(Map<String, Object> param) throws Exception {
        // 记录传入参数的日志信息
        log.info("数据ID:" + JSON.toJSONString(param));

        // 初始化数据映射和结果映射
        Map<String, Object> dataMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();

        try {
            // 提取并验证数据ID
            String dataId = StrKit.str(param.get("dataId"));
            if ("".equals(dataId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "数据ID不能为空值");
                resultMap.put("data", dataMap);
                return ok(resultMap);
            }

            // 提取并验证用户ID
            String userId = StrKit.str(param.get("userId"));
            if ("".equals(userId)) {
                resultMap.put("code", 500);
                resultMap.put("message", "人员ID不能为空值");
                resultMap.put("data", dataMap);
                return ok(resultMap);
            }
            String loginName = orgManager.getMemberById(Long.parseLong(userId)).getLoginName();

            // 获取表单信息
            FormBean formBean = cap4FormManager.getFormByFormCode(zcda_unFlowformCode);

            // 获取资产档案表的数据对象
            FormDataMasterBean formDataMasterBean = cap4FormManager.getDataMasterBeanById(Long.parseLong(dataId.trim()), formBean, null);
            if (param.containsKey("isTakeStock")) {
                String isTakeStock = StrKit.str(param.get("isTakeStock"));
                if ("领用".equals(isTakeStock)) {
                    String assetNum = StrKit.str(formDataMasterBean.getFieldValue(formBean.getFieldBeanByDisplay("资产编号").getName()));
                    String assetName = StrKit.str(formDataMasterBean.getFieldValue(formBean.getFieldBeanByDisplay("资产名称").getName()));
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("appName", "collaboration");
                    Map<String, Object> paramData = new HashMap<String, Object>();
                    paramData.put("templateCode", zcly_lowformCode);
                    paramData.put("draft", "1");
                    Map<String, Object> assetDataMap = new HashMap<String, Object>();
                    Map<String, Object> mainMap = new HashMap<String, Object>();
                    FormBean zcly_formBean = cap4FormManager.getFormByFormCode(zcly_lowformCode);
                    assetDataMap.put(zcly_formBean.getMasterTableBean().getTableName(), mainMap);
                    String zcly_subTableName = zcly_formBean.getSubTableBean().get(0).getTableName();
                    Map<String, Object> subMap = new HashMap<String, Object>();
                    List<Map<String, Object>> subList = new ArrayList<Map<String, Object>>();
                    subMap.put("资产编号", assetNum);
                    subMap.put("资产名称", assetName);
                    subList.add(subMap);
                    assetDataMap.put(zcly_subTableName, subList);
                    paramData.put("data", assetDataMap);
                    map.put("data", paramData);

                    String dataJson = JSON.toJSONString(map);
                    String tokenId = HttpKit.getToken(loginName, tokenUrl);
                    if ("".equals(tokenId)) {
                        resultMap.put("type", "E");
                        resultMap.put("msg", "获取token失败");
                        resultMap.put("affairId", "");
                        return ok(resultMap);
                    }
                    log.info("发送资产盘点登记单协同数据json:" + dataJson);
                    Map<String, Object> headerMap = new HashMap<String, Object>();
                    headerMap.put("token", tokenId);
                    String result = HttpKit.post(bpmUrl, headerMap, dataJson);
                    log.info("发送资产领用单协同返回信息:" + result);
                    JSONObject resultObj = JSONObject.parseObject(result);
                    String code = StrKit.str(resultObj.get("code"));
                    if ("0".equals(code)) {
                        JSONObject dataMsgObj = resultObj.getJSONObject("data");
                        JSONObject bussinessObj = dataMsgObj.getJSONObject("app_bussiness_data");
                        String affairId = StrKit.str(bussinessObj.get("affairId"));
                        // 返回成功结果
                        resultMap.put("code", 200);
                        resultMap.put("message", "领用成功!");
                        resultMap.put("affairId", affairId);
                    }else{
                        resultMap.put("code", 500);
                        String message = StrKit.str(resultObj.get("code"));
                        resultMap.put("message", "领用成功!");
                        resultMap.put("affairId", "");
                    }
                } else {
                    // 处理盘点人员的子表数据
                    String subTableName = formBean.getFieldBeanByDisplay("盘点人员").getOwnerTableName();
                    List<FormDataSubBean> formDataSubBeans = formDataMasterBean.getSubData(subTableName);
                    FormTableBean formTableBean = null;
                    if (!formDataSubBeans.isEmpty()) {
                        formTableBean = formDataSubBeans.get(0).getFormTable();
                        for (FormDataSubBean formDataSubBean : formDataSubBeans) {

                            String inventoryMemberId = StrKit.str(formDataSubBean.getFieldValue(formBean.getFieldBeanByDisplay("盘点人员").getName()));
                            if ("".equals(inventoryMemberId)) {
                                formDataSubBeans.remove(formDataSubBean);
                                break;
                            }
                        }
                    }
                    boolean isNew = false;
                    // 如果没有获取到子表信息，则返回错误信息
                    if (formTableBean == null) {
                        resultMap.put("code", 500);
                        resultMap.put("message", "未获取到盘点记录明细表信息!");
                        return ok(resultMap);
                    }

                    // 准备新的子表数据映射
                    HashMap<String, Object> subMap = new HashMap<String, Object>();
                    subMap.put(formBean.getFieldBeanByDisplay("盘点日期").getName(), new Date());
                    subMap.put(formBean.getFieldBeanByDisplay("盘点人员").getName(), userId);
                    // 盘点结果(已盘点)
                    CtpEnumItem ctpEnumItem = enumManagerNew.getItemByCode("YPD");
                    subMap.put(formBean.getFieldBeanByDisplay("盘点结果").getName(), ctpEnumItem.getId());

                    // 创建并保存新的子表数据对象
                    FormDataSubBean formDataSubBean_new = new FormDataSubBean(subMap, formTableBean, formDataMasterBean, true);
                    formDataSubBean_new.setIdIfNew();
                    formDataSubBean_new.setFormmainId(formDataMasterBean.getId());
                    formDataMasterBean.addSubData(formTableBean.getTableName(), formDataSubBean_new);
                    cap4FormManager.saveOrUpdateFormData(formDataMasterBean, formBean.getId(), true, null);
                    // 返回成功结果
                    resultMap.put("code", 200);
                    resultMap.put("message", "盘点成功!");
                }
            }

            return ok(resultMap);
        } catch (Exception e) {
            // 记录异常信息并返回错误结果
            log.error("盘点接口异常信息:", e);
            resultMap.put("code", 500);
            resultMap.put("message", e.getMessage());
            return ok(resultMap);
        }
    }

    /**
     * 根据字段类型获取并转换字段值
     * 此方法旨在根据不同类型的字段，将给定的字段值转换为更易读或特定格式的形式
     * 例如，对于枚举类型的字段，它会查找枚举项的显示值；对于日期类型，它会格式化日期
     *
     * @param fieldValue 字段的原始值如果为空字符串，则直接返回空字符串
     * @param fieldType  字段的类型，决定如何处理字段值
     * @return 转换或格式化后的字段值如果输入为空，则返回空字符串
     * @throws Exception 如果解析或转换过程中发生错误，抛出异常
     */
    private String getData(String fieldValue, String fieldType) throws Exception {
        // 初始化处理后的字段值
        String fieldValue_new = "";
        // 检查字段值是否不为空
        if (!"".equals(fieldValue)) {
            // 根据字段类型处理字段值
            if ("imageselect".equals(fieldType) || "radio".equals(fieldType) || "select".equals(fieldType)) {
                // 对于枚举类型的字段（如图片选择、单选按钮、下拉选择），获取其显示值
                fieldValue_new = enumManagerNew.getCtpEnumItem(Long.parseLong(fieldValue)).getShowvalue();
            } else if ("date".equals(fieldType)) {
                // 对于日期类型的字段，格式化为"yyyy-MM-dd"格式
                fieldValue_new = new SimpleDateFormat("yyyy-MM-dd").format(sdf.parse(fieldValue));
            } else if ("department".equals(fieldType)) {
                // 对于部门类型的字段，获取部门名称
                fieldValue_new = orgManager.getDepartmentById(Long.parseLong(fieldValue)).getName();
            } else if ("member".equals(fieldType)) {
                // 对于成员类型的字段，获取成员名称
                fieldValue_new = orgManager.getMemberById(Long.parseLong(fieldValue)).getName();
            } else if ("account".equals(fieldType)) {
                // 对于账户类型的字段，获取账户名称
                fieldValue_new = orgManager.getAccountById(Long.parseLong(fieldValue)).getName();
            } else {
                // 对于其他未知或不需要转换的字段类型，直接返回原始字段值
                fieldValue_new = fieldValue;
            }
        } else {
            // 如果字段值为空字符串，直接返回空字符串
            fieldValue_new = fieldValue;
        }
        // 返回处理后的字段值
        return fieldValue_new;
    }


}
